<?php
// scripts/generate_requests.php
require_once __DIR__ . '/../vendor/autoload.php';

use ReflectionClass;
use ReflectionMethod;

class WebmanRequestGenerator
{
    private $controllerPath;
    private $requestPath;
    private $namespace;

    public function __construct()
    {
        $this->controllerPath = __DIR__ . '/../app/api/controller/';
        $this->requestPath = __DIR__ . '/../app/api/request/';
        $this->namespace = 'app\\api\\request';

        // 确保request目录存在
        if (!is_dir($this->requestPath)) {
            mkdir($this->requestPath, 0755, true);
        }
    }

    public function generateRequests()
    {
        $controllers = $this->getControllers();
        
        foreach ($controllers as $controller) {
            $this->generateRequestForController($controller);
        }
    }

    private function getControllers()
    {
        $controllers = [];
        $files = glob($this->controllerPath . '*.php');
        
        foreach ($files as $file) {
            $controllers[] = basename($file, '.php');
        }
        
        return $controllers;
    }

    private function generateRequestForController($controllerName)
    {
        $controllerClass = "app\\api\\controller\\{$controllerName}";
        
        if (!class_exists($controllerClass)) {
            echo "Controller class {$controllerClass} not found, skipped.\n";
            return;
        }

        $reflection = new ReflectionClass($controllerClass);
        $methods = $reflection->getMethods(ReflectionMethod::IS_PUBLIC);
        
        // 去掉 "Controller" 后缀
        $baseName = str_replace('Controller', '', $controllerName);
        $requestClassName = $baseName . 'Request';
        $requestFilePath = $this->requestPath . $requestClassName . '.php';
        
        $content = $this->generateRequestContent($requestClassName, $methods);
        
        // 如果文件已存在，只更新方法验证规则部分
        if (file_exists($requestFilePath)) {
            $this->updateExistingRequest($requestFilePath, $content, $methods);
        } else {
            file_put_contents($requestFilePath, $content);
            echo "Generated request: {$requestClassName}.php\n";
        }
    }

    private function generateRequestContent($className, $methods)
    {
        $methodRules = $this->generateMethodRules($methods);
        
        return "<?php

namespace {$this->namespace};

use app\\api\\BaseRequest;

/**
 * {$className}
 * 
 * 自动生成的请求验证类
 */
class {$className} extends BaseRequest
{
{$methodRules}

    /**
     * 获取验证错误消息
     *
     * @return array
     */
    public function messages(): array
    {
        return [
            // 在这里添加自定义错误消息
        ];
    }

    /**
     * 获取验证属性名称
     *
     * @return array
     */
    public function attributes(): array
    {
        return [
            // 在这里添加属性名称映射
        ];
    }
}
";
    }

    private function generateMethodRules($methods)
    {
        $rules = [];
        
        foreach ($methods as $method) {
            $methodName = $method->getName();
            
            // 跳过构造函数和私有方法
            if ($methodName === '__construct' || $method->isPrivate() || $method->isProtected()) {
                continue;
            }
            
            $rules[] = $this->generateMethodRule($methodName);
        }
        
        return implode("\n", $rules);
    }

    private function generateMethodRule($methodName)
    {
        $ucMethodName = ucfirst($methodName);
        
        return "    /**
     * {$methodName} 方法的验证规则
     *
     * @return array
     */
    public function getRulesBy{$ucMethodName}(): array
    {
        return [
            // 在这里添加 {$methodName} 方法的验证规则
            // 例如：
            // 'username' => 'require|alphaNum|length:5,64',
            // 'email' => 'require|email',
            // 'age' => 'require|number|between:18,100',
        ];
    }";
    }



    private function updateExistingRequest($filePath, $newContent, $methods)
    {
        $existingContent = file_get_contents($filePath);
        
        // 检查是否需要更新方法验证规则
        $needsUpdate = false;
        foreach ($methods as $method) {
            $methodName = $method->getName();
            if ($methodName === '__construct' || $method->isPrivate() || $method->isProtected()) {
                continue;
            }
            
            $ruleMethodName = 'getRulesBy' . ucfirst($methodName);
            if (strpos($existingContent, $ruleMethodName) === false) {
                $needsUpdate = true;
                break;
            }
        }
        
        if ($needsUpdate) {
            // 提取现有内容中的类定义部分
            $pattern = '/class\s+\w+Request\s+extends\s+Request\s*\{/';
            if (preg_match($pattern, $existingContent, $matches)) {
                $classStart = $matches[0];
                $classStartPos = strpos($existingContent, $classStart);
                
                // 找到类的结束位置
                $braceCount = 0;
                $classEndPos = $classStartPos;
                $inClass = false;
                
                for ($i = $classStartPos; $i < strlen($existingContent); $i++) {
                    $char = $existingContent[$i];
                    if ($char === '{') {
                        $braceCount++;
                        $inClass = true;
                    } elseif ($char === '}') {
                        $braceCount--;
                        if ($inClass && $braceCount === 0) {
                            $classEndPos = $i;
                            break;
                        }
                    }
                }
                
                // 保留现有的类内容，只添加缺失的方法验证规则
                $existingClassContent = substr($existingContent, $classStartPos, $classEndPos - $classStartPos + 1);
                
                // 生成新的方法验证规则
                $newMethodRules = $this->generateMethodRules($methods);
                
                // 在现有类内容中插入新的方法验证规则
                $insertPos = strrpos($existingClassContent, '}');
                if ($insertPos !== false) {
                    $updatedClassContent = substr($existingClassContent, 0, $insertPos) . "\n{$newMethodRules}\n" . substr($existingClassContent, $insertPos);
                    
                    // 更新文件内容
                    $updatedContent = substr($existingContent, 0, $classStartPos) . $updatedClassContent . substr($existingContent, $classEndPos + 1);
                    file_put_contents($filePath, $updatedContent);
                    echo "Updated request with new method rules.\n";
                }
            }
        } else {
            echo "Request file already up to date.\n";
        }
    }
}

// 使用示例
$generator = new WebmanRequestGenerator();

// 生成所有请求验证类
$generator->generateRequests();

echo "Request generation completed!\n"; 